/** 快速排序法： 适合英文、数字
 * 泛型函数格式：函数名<泛型类型>(参数中可以使用泛型类型)：返回值也可以是泛型类型 **/
function quickSort<T>(arr: Array<T>): Array<T> {
  if (arr.length < 2) return arr

  var left: Array<T> = []
  var right: Array<T> = []
  var mid = arr.splice(Math.floor(arr.length / 2), 1)[0]
  for(let i = 0; i < arr.length; i++) {
    if (arr[i] === mid) continue; // 跳过基准元素
    if (arr[i] < mid) {
      left.push(arr[i])
    } else {
      right.push(arr[i])
    }
  }
  return quickSort(left).concat([mid], quickSort(right))
}

// 中文排序
function sortChinese<T>(arr: Array<T>): Array<T> {
  return arr.sort(function (prev, next) {
    return (prev as any).localeCompare(next, 'zh-CN')
  })
}
let chineseArr = ['武汉', '郑州', '太原', '济南', '沈阳', '大连']

// 字符串自排序
function strSelfSort(str: string): string {
  let strArray = str.split('')
  let strSortArray = quickSort(strArray)
  return strSortArray.join('')
}
let str = 'hskdgggkcsairthjashkio' // 对自己字符串排序

// 判断是否有中文元素
function isChinese<T>(data: T):boolean {
  var pattern = /[\u4e00-\u9fa5]+/g
  if (typeof data === 'string') {
    return pattern.test(data)
  }
  if (data instanceof Array) {
    return data.some(item => {
      return pattern.test(item as any)
    })
  }
}

/** 中文+英文、数字数组排序混合方法
 * 注意 sort<T>(data: T): T[] | string  返回写这种T[] | string不好，所以换成函数重载 **/ 
function sort(data: string): string
function sort<T>(data: T): T
function sort(data: any): any {
  if (typeof data === 'string') { // 如果data是字符串
    return strSelfSort(data)
  }
  if (data instanceof Array) { // 如果data是数组
    if (isChinese(data)) { // 如果是中文数组
      return sortChinese(data)
    }
    let newArray = data.map(item => {
      return typeof item === 'string' ? strSelfSort(item) : item
    })
    return quickSort(newArray as any)
  }
  
}


/** 泛型工厂函数：一个可以创建任意类对象的通用函数 **/
// 函数类型
type promiseFuncTpe = (resolve: string, reject: string) => any
let promiseFunc: promiseFuncTpe = function(resolve, reject): void {
  console.log(resolve, reject)
}
promiseFunc('resolve', 'reject')

// 通用函数类型
type commonFunc = (...args: any) => any // 第一种写法
interface commonFuncInter { // 第二种写法，跟第一种写法一样
  (...args:any): any // 调用签名
}
let func: commonFunc = function(count:string, money:number): void {

}

// TS没办法直直接new一个函数
// 工厂函数类型：代表任意一个类的构造函数【等价于JS的构造函数】的函数类型
type ConstructorType = new (...args:any) => any

/** 工厂函数和泛型工厂函数 **/
// 泛型工厂函数【一些不方便，比如说为每一个类对象创建时都打印一句】
function createInstanceFunctory<T>(Constructor: { new(...arg: any): T }) {
  console.log(Constructor.name + '被创建对象')
  return new Constructor()
}
class Blank {

}
// 使用工厂函数开创建我们的类
let con = createInstanceFunctory<Blank>(Blank)

// 泛型工厂装饰器写法
type MyClassDecorator = <T>(targetClass: new(...args: any) => T) => any
function Controller(rootPath: string): MyClassDecorator {
  return function (targetClass) {

  }
}

